package com.vt.common.security.util;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.vt.admin.api.dto.user.redis.UserOrganization;
import com.vt.common.core.constant.CommonConstant;
import com.vt.common.security.util.enums.DataScopeType;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 组织工具
 */
@Component
@AllArgsConstructor
public class OrganizationUtil {

    StringRedisTemplate redisTemplate;

    /**
     * 所属管理公司，如果managerId 是管理公司，则 return managerId
     *
     * @param managerId
     * @return
     */
    public String searchOrgMgCompany(String managerId) {
        List<UserOrganization> list = getOrgan();

        UserOrganization organ = null;

        for (UserOrganization obj : list) {
            if (StrUtil.equals(obj.getOrganizationId(), managerId)) {
                organ = obj;
                break;
            }
        }

        if (null == organ || isMg(organ))
            return managerId;

        if (isPlatform(organ))
            return "";

        UserOrganization[] mg = new UserOrganization[1];
        searchMg(organ, list, mg);

        return null == mg[0] ? "" : mg[0].getOrganizationId();
    }

    private void searchMg(UserOrganization organ, List<UserOrganization> list, UserOrganization[] rs) {

        for (UserOrganization obj : list) {
            if (StrUtil.equals(obj.getOrganizationId(), organ.getParentId())) {

                if (isMg(obj)) {
                    rs[0] = obj;
                    return;
                }

                searchMg(obj, list, rs);
            }
        }
    }


    private boolean isMg(UserOrganization organ) {
        return (DataScopeType.COMPANY_MANAGER.code + "").equals(organ.getType());
    }

    private boolean isPlatform(UserOrganization organ) {
        return (DataScopeType.PLATFORM_MANAGER.code + "").equals(organ.getType());
    }

    /**
     * @param root 组织ID
     * @return 下级组织ID
     */
    public Set<String> children(String... root) {
        List<UserOrganization> all = getOrgan();
        if (ArrayUtil.isEmpty(root)
                || (root.length == 1 && StrUtil.isEmpty(root[0]))) {
            root = getByUserId(all, SecurityUtils.getUser().getId());
        }

        Set<String> chs = new HashSet();
        for (int i = 0, len = root.length; i < len; i++) {
            chs.addAll(getChs(all, root[i]));
        }

        chs.addAll(Arrays.asList(root));
        return chs;
    }

    public String[] currUserOrganization() {
        return getByUserId(getOrgan(), SecurityUtils.getUser().getId());
    }

    private Collection<? extends String> getChs(Collection<UserOrganization> all, String id) {
        Set<String> chs = new HashSet();
        searchChs(id, all, chs);
        return chs;
    }

    private void searchChs(String id, Collection<UserOrganization> all, Set<String> chs) {
        for (UserOrganization obj : all) {
            if (StrUtil.equals(id, obj.getParentId())) {
                chs.add(obj.getOrganizationId());

                searchChs(obj.getOrganizationId(), all, chs);
            }
        }
    }


    private List<UserOrganization> getOrgan() {
        return JSONUtil.toList(JSONUtil.parseArray(
                redisTemplate.opsForValue().get(CommonConstant.REDIS_ORGANIZATION_PREFIX))
                , UserOrganization.class);
    }

    private String[] getByUserId(Collection<UserOrganization> all, String userId) {
        List<String> list = new ArrayList();

        for (UserOrganization item : all) {
            if (StrUtil.equals(userId, item.getUserId())) {
                list.add(item.getOrganizationId());
            }
        }
        return ArrayUtil.toArray(list, String.class);
    }
}
